<template>
  <div class="row relative-position">
    <div class="col-8 relative-position q-pa-md" style="height: 100%">
      <q-card
        class="bg-half-black text-white"
        style="
          width: 100%;
          height: 100%;
          display: flex;
          justify-content: center;
        "
      >
        <img
          src="/postPure/empty.svg"
          alt=""
          style="width: 100%; height: 100%"
          ref="imgRef"
        />
        <div class="cross"></div>
      </q-card>
    </div>
    <div class="col-4 q-pa-md">
      <q-card class="bg-half-black text-white full-height column">
        <div class="col-2 row">
          <q-btn
            no-caps
            @click="handleCameraPreview"
            class="col-6 text-space text-h5"
            :loading="isPreview"
          >
            {{ $t("selfCalibrate.相机预览") }}
            <template v-slot:loading>
              <q-spinner-hourglass class="on-left" />
              {{ $t("selfCalibrate.准备中") }}
            </template>
          </q-btn>
          <q-btn
            no-caps
            @click="handleCalibration"
            class="col-6 text-space text-h5"
            :loading="isCalibration"
          >
            {{ $t("selfCalibrate.一键标定") }}
            <template v-slot:loading>
              <q-spinner-hourglass class="on-left" />
              {{ $t("selfCalibrate.标定中") }}
            </template>
          </q-btn>
        </div>
        <div class="col-10 row">
          <div class="col-6 overflow-hidden text-center q-pt-md">
            <div
              class="text-h6 q-pb-md"
              style="border-bottom: 2px #28292a solid"
            >
              {{ $t("selfCalibrate.上次标定结果") }}
            </div>
            <div style="border-right: 1px #28292a solid; height: 100%">
              <div
                class="q-pt-sm q-pb-sm text-body1 text-weight-bold"
                v-for="(value, key) in lastCalibrationData"
                :key="key"
              >
                <template v-if="key !== 'flag'">
                  {{ key + "：" + value.toFixed(6) }}
                </template>
              </div>
            </div>
          </div>
          <div class="col-6 overflow-hidden text-center q-pt-md">
            <div
              class="text-h6 q-pb-md"
              style="border-bottom: 2px #28292a solid"
            >
              {{ $t("selfCalibrate.当前标定结果") }}
            </div>
            <div style="border-left: 1px #28292a solid; height: 100%">
              <template v-for="(value, key) in calibrationData" :key="key">
                <div
                  class="q-pt-sm q-pb-sm text-body1 text-weight-bold"
                  v-if="key !== 'flag'"
                >
                  {{ key + "：" + value }}
                </div>
              </template>
              <q-btn
                label="保存"
                style="border: 1px solid rgba(128, 128, 128, 0.4)"
                class="full-width"
                v-if="Object.values(calibrationData).length !== 0"
                @click="save"
              />
            </div>
          </div>
        </div>
      </q-card>
    </div>
    <q-dialog v-model="visible" persistent>
      <q-card>
        <q-card-section>
          <span class="text-h5">提示</span>
        </q-card-section>
        <q-card-section class="row items-center">
          <span
            class="q-ml-md text-subtitle1 q-mr-md"
            style="word-break: break-all"
            >{{ negativeData }}</span
          >
        </q-card-section>
        <q-card-actions align="right">
          <q-btn
            flat
            label="消除警报"
            color="primary"
            size="1rem"
            v-close-popup
            class="q-mr-sm"
            @click="abort"
          />
          <!--          <q-btn flat label="知道了" color="primary" size="1rem" v-close-popup class="q-mr-sm"/>-->
        </q-card-actions>
      </q-card>
    </q-dialog>
  </div>
</template>
<script setup>
import RosClient from "src/utils/rosClient";
import { onMounted, onUnmounted, ref } from "vue";

import { api } from "boot/axios.js";
import { Dialog, useQuasar } from "quasar";
import { useAPIStore } from "src/stores/api";
import { useUiStore } from "stores/ui";
import { showNotify } from "src/utils/tools";
import { v4 as uuidv4 } from "uuid";
import { useI18n } from "vue-i18n";

const t = useI18n().t; // 语言包
const $q = useQuasar();
const ui = useUiStore();
const rosClient = RosClient();
const isDark = ui.isDark;
const isCalibration = ref(false); // 是否标定中，控制一键标定按钮是否可点击
const calibrationData = ref({}); // 此次标定数据
const lastCalibrationData = ref({}); // 上次标定数据
const isPreview = ref(false); // 是否相机预览中，控制相机预览按钮是否可点击
const isTow = ref(true); // 是否为第一次
const imgRef = ref();
const visible = ref(false);
const negativeData = ref("");
/* -------------------------------------------------------------------------- */
// onBeforeMount(() => {
//   rosClient.createWs()
// })

onMounted(() => {
  // rosClient.subscribe('/raw_img') // 完成标定
  // if (isCalibration.value) { // 在getCalibrateState中去获取
  //   getImg() // 获取标定中的图片
  // }
  getPose();
  getCalibrateState();
});

onUnmounted(() => {
  if (timer) clearTimeout(timer);
  // rosClient.unsubscribe('/raw_img')
});
/* -------------------------------------------------------------------------- */
// watch(rosClient.rawImg, () => {
//   // 标定中发生改变获取
//   getImg()
//   // 判断只有不在一键标定的时候
//   if (!isCalibration.value) {
//     // 判断是否为第一次请求接口/raw
//     if (isTow.value) {
//       handleCameraPreview()
//       isTow.value = false
//       isPreview.value = false
//     }
//     isPreview.value = false
//   }
// })

/* -------------------------------------------------------------------------- */
let timer;

function getCalibrateState() {
  getImg();
  api
    .get(useAPIStore().amrUrl + "ros/param?param=calibrate_state")
    .then((res) => {
      const data = JSON.parse(JSON.parse(res.data.value));
      switch (data.state) {
        // 标定中
        case "in_calibrate":
          isCalibration.value = true;
          isPreview.value = true;
          break;
        // 标定完成
        case "end":
          if (data.result !== "failed") {
            calibrationData.value = data.data;
          } else {
            negativeData.value = data.data;
            visible.value = true;
          }
          isCalibration.value = false;
          isPreview.value = false;
          break;
        // 未开始
        case "initial":
          isPreview.value = false;
          break;
        default:
          break;
      }
    })
    .catch(() => {});
  timer = setTimeout(getCalibrateState, 1000);
}

// 消除报警
function abort() {
  api
    .post(
      useAPIStore().amrUrl + "ros/call",
      { data: "calibrate" },
      { params: { service: "/calibrate_state_reset" } }
    )
    .then((res) => {
      if (res.data.values.result === "SUCCESS") {
        visible.value = false;
        $q.notify({
          type: "positive",
          message: "报警消除成功！",
        });
      } else {
        $q.notify({
          type: "negative",
          message: "报警消除失败！",
        });
      }
    })
    .catch(() => {
      $q.notify({
        type: "negative",
        message: "接口请求异常！",
      });
    });
}

// 获取拍照信息
function getImg() {
  console.log("----", imgRef.value.src);
  const uuid = uuidv4();
  imgRef.value.src = `${
    useAPIStore().rosImgUrl
  }snapshot?topic=/raw_img&quality=50&rad=${uuid}`;
}

// 获取配置文件中的内参标定结果
function getPose() {
  api
    .post(
      useAPIStore().amrUrl + "ros/call",
      {
        target_frame: "flange",
        source_frame: "camera",
      },
      { params: { service: "tf/get_frame_pose" } }
    )
    .then((res) => {
      const posture = res.data.values.pose;
      lastCalibrationData.value.x = posture.pose.position.x;
      lastCalibrationData.value.y = posture.pose.position.y;
      lastCalibrationData.value.z = posture.pose.position.z;
      lastCalibrationData.value.qx = posture.pose.orientation.x;
      lastCalibrationData.value.qy = posture.pose.orientation.y;
      lastCalibrationData.value.qz = posture.pose.orientation.z;
      lastCalibrationData.value.qw = posture.pose.orientation.w;
    });
}

/**
 * 相机预览
 */
async function handleCameraPreview() {
  isPreview.value = true;
  try {
    const response = await api.post(
      useAPIStore().amrUrl + "ros/call",
      {},
      { params: { service: "/raw" } }
    );
    if (response.data.values.flag !== 1) {
      isPreview.value = false;
      showNotify(response.data.values.message);
    }
  } catch (e) {
    isPreview.value = false;
    showNotify(e.message);
  }
  getImg();
}

/**
 * 一键标定
 */
async function handleCalibration() {
  isCalibration.value = true;
  try {
    const response = await api.post(
      useAPIStore().amrUrl + "ros/call",
      { data: "calibrate" },
      { params: { service: "/calibrate_server" } }
    );
    if (response.data.values.result === "SUCCESS") {
      isCalibration.value = false;
    } else {
      // 标定service调用失败
      isCalibration.value = false;
      Dialog.create({
        title: t("tips"),
        dark: isDark,
        message:
          t("selfCalibrate.检查相机是否开机或是否对准二维码") +
          "（" +
          response.data.values.result +
          "）",
      });
    }
  } catch (e) {
    isCalibration.value = false;
    showNotify(e.message);
  }
}

// 保存标定结果到ros文件
function save() {
  const posture = {
    parent: "flange",
    child: "camera",
    pose: {
      orientation: {
        x: "",
        y: "",
        z: "",
        w: "",
      },
      position: {
        x: "",
        y: "",
        z: "",
      },
    },
  };
  posture.pose.position.x = Number(calibrationData.value.x);
  posture.pose.position.y = Number(calibrationData.value.y);
  posture.pose.position.z = Number(calibrationData.value.z);
  posture.pose.orientation.x = Number(calibrationData.value.qx);
  posture.pose.orientation.y = Number(calibrationData.value.qy);
  posture.pose.orientation.z = Number(calibrationData.value.qz);
  posture.pose.orientation.w = Number(calibrationData.value.qw);
  api
    .post(useAPIStore().amrUrl + "ros/call", posture, {
      params: { service: "/tf/commit_tf" },
    })
    .then((res) => {
      if (res.data.values.success) {
        $q.notify({
          type: "positive",
          message: "内参数据保存成功！",
        });
      } else {
        $q.notify({
          type: "negative",
          message: "内参数据保存失败",
        });
      }
    })
    .catch(() => {
      $q.notify({
        type: "negative",
        message: "接口请求异常",
      });
    });
}
</script>
<style lang="scss" scoped>
.cross {
  width: 50px;
  height: 50px;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  position: absolute;
}

.cross::before {
  content: "";
  width: 100%;
  height: 4px;
  background-color: red;
  position: absolute;
  left: 0;
  top: 50%;
  transform: translateY(-50%);
}

.cross::after {
  content: "";
  width: 4px;
  height: 100%;
  background-color: red;
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
}
</style>
